package com.piece.module.file.util.excel;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.metadata.CellExtra;
import com.alibaba.excel.read.listener.ReadListener;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.util.*;
import java.util.function.Function;

/**
 * 读取Excel监听器
 */
@Data
@Slf4j
public class ExcelReadListener<T> implements ReadListener<T> {

    private Function<List, Void> invokeFun;
    private boolean readExtra = false;
    private int startRow;
    private int endRow;
    private int batchCount;
    private List<T> cacheDataList;

    public ExcelReadListener(ExcelParam param, Function<List, Void> invokeFun) {
        this.invokeFun = invokeFun;
        initParam(param);
    }

    public ExcelReadListener(ExcelParam param, Function<List, Void> invokeFun, boolean readExtra) {
        this.invokeFun = invokeFun;
        this.readExtra = readExtra;
        initParam(param);
    }

    private void initParam(ExcelParam param) {
        this.startRow = param.getReadStartRow();
        this.endRow = param.getReadEndRow();
        this.batchCount = param.getBatchCount();
        this.cacheDataList = new ArrayList<>();
    }

    /**
     * 每读取一行数据调用
     */
    @Override
    public void invoke(T data, AnalysisContext context) {
        int rowIndex = context.readRowHolder().getRowIndex();
        if (rowIndex >= startRow && (rowIndex <= endRow || endRow == 0)) {
            cacheDataList.add(data);
        }

        if (cacheDataList.size() >= batchCount) {
            if (null != invokeFun) {
                invokeFun.apply(cacheDataList);
            }
            cacheDataList.clear();
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        if (null != invokeFun && cacheDataList.size() > 0) {
            invokeFun.apply(cacheDataList);
        }
        cacheDataList.clear();
    }

    /**
     * 读取额外信息
     */
    @Override
    public void extra(CellExtra extra, AnalysisContext context) {
        if (readExtra) {
            log.info("开始读取Excel额外信息");
            switch (extra.getType()) {
                case COMMENT:
                    log.info("第({})行第({})列批注信息：{}", extra.getRowIndex(), extra.getColumnIndex(), extra.getText());
                    break;
                case MERGE:
                    if ("Sheet1!A1".equals(extra.getText())) {
                        log.info("第({})行第({})列超链接：{}", extra.getRowIndex(), extra.getColumnIndex(), extra.getText());
                    } else if ("Sheet2!A1".equals(extra.getText())) {
                        log.info("从第({})行第({})列到第({})行第({})列超链接：{}",
                                extra.getFirstRowIndex(), extra.getFirstRowIndex(),
                                extra.getLastRowIndex(), extra.getLastColumnIndex(),
                                extra.getText());
                    } else {
                        log.info("未知超链接");
                    }
                    log.info("第({})行第({})列批注信息：{}", extra.getRowIndex(), extra.getColumnIndex(), extra.getText());
                    break;
                case HYPERLINK:
                    log.info("从第({})行第({})列到第({})行第({})列超链接：{}",
                            extra.getFirstRowIndex(), extra.getFirstRowIndex(),
                            extra.getLastRowIndex(), extra.getLastColumnIndex(),
                            extra.getText());
                    break;
                default:
            }
            log.info("结束读取Excel额外信息");
        }
    }
}
